package com.ss.web.tagmark.service;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.github.stuxuhai.jpinyin.PinyinFormat;
import com.github.stuxuhai.jpinyin.PinyinHelper;
import com.ss.web.tagmark.dao.UserDao;
import com.ss.web.tagmark.dao.UserTagDao;
import com.ss.web.tagmark.entity.TagInfo;
import com.ss.web.tagmark.entity.User;
import com.ss.web.tagmark.entity.UserTag;
import com.ss.web.tagmark.utils.ReflectUtils;

@Service
public class UserService extends BaseService<User> implements UserDetailsService {
	@Autowired
	private UserDao userDao;
	@Autowired
	private UserTagDao userTagDao;
	@Autowired
	private TagService tagService;

	public User getById(Long userId) {
		if (userId == null) {
			return null;
		}
		Optional<User> user = userDao.findById(userId);
		return user == null ? null : user.get();
	}

	/**
	 * 根据查询内容，在各个字段上搜索并将搜索到的结果返回
	 *
	 * @param q
	 *            在域账号、姓名、标签
	 * @return
	 */
	public List<User> find4Search(String q) {
		return userDao.find4Search(q);
	}

	/**
	 * 新增一个用户，同时增加一些标签
	 *
	 * @param user
	 * @param newTags
	 */
	@Transactional
	public void add(User user, String newTags) {
		valid(user, false);
		// 下面初始化一些数据，其实不初始化也没关系，因为数据库有默认值
		user.setPassword("123456a");// 默认密码，为以后扩展留
		user.setStatus(User.STATUS_ACTIVE);
		userDao.save(user);// 保存
		saveUserTag(user, newTags);
	}

	@Transactional
	public void update(User user, String newTags) {
		valid(user, true);
		User db = getById(user.getUserId());
		ReflectUtils.copyNotNullProperties(user, db);// 将非空的内容复制到数据库中
		userDao.save(db);
		// 删除对应的关系
		userTagDao.deleteByUserId(user.getUserId());
		saveUserTag(user, newTags);
	}

	/**
	 * 删除一个用户，逻辑删除，基础数据一律逻辑删除
	 *
	 * @param userId
	 */
	@Transactional
	public void deleteById(Long userId) {
		User db = getById(userId);
		db.setStatus(User.STATUS_INACTIVE);
		userDao.save(db);
	}

	private void valid(User user, boolean isModify) {
		if (isModify) {
			if (user.getUserId() == null) {
				throw new IllegalArgumentException("没有指定id，无法修改！");
			}
		}
		if (StringUtils.isBlank(user.getFullname())) {
			throw new IllegalArgumentException("姓名不能为空！");
		}
		if (StringUtils.isBlank(user.getLogname())) {
			throw new IllegalArgumentException("域账号不能为空！");
		}
		user.setFullname(user.getFullname().replaceAll("\\s|　", ""));// 名字中的空格去除
		user.setLogname(user.getLogname().replaceAll("\\s|　", ""));
		boolean exists = false;
		// 域账号不能相同
		if (isModify) {
			exists = userDao.existsByLognameAndUserIdNot(user.getLogname(), user.getUserId());
		} else {
			exists = userDao.existsByLogname(user.getLogname());
		}
		if (exists) {
			throw new IllegalArgumentException("该域账号已经存在！");
		}
		// 处理fullname的拼音
		try {
			String py = PinyinHelper.convertToPinyinString(user.getFullname(), "", PinyinFormat.WITHOUT_TONE);
			String pyshort = PinyinHelper.getShortPinyin(user.getFullname());
			user.setFullnamePy(py);
			user.setFullnamePyShort(pyshort);
		} catch (Exception e) {
			logger.error("汉字转拼音失败了！" + e, e);
		}
	}

	/**
	 * @param user
	 * @param newTags
	 */
	private void saveUserTag(User user, String newTags) {
		// 将新增的tag添加进去
		List<TagInfo> tags = user.getTags();
		if (StringUtils.isNotBlank(newTags)) {
			List<TagInfo> nts = tagService.batchAdd(newTags.split(",|，"));
			if (nts != null && nts.size() > 0) {
				if (tags != null) {
					tags.addAll(nts);
				} else {
					tags = nts;
				}
			}
		}
		// 增加关联信息
		if (tags != null && tags.size() > 0) {
			Set<TagInfo> _tags = new LinkedHashSet<>();
			_tags.addAll(tags);// 去重
			for (TagInfo tag : _tags) {
				UserTag u = new UserTag();
				u.setUserId(user.getUserId());
				u.setTagId(tag.getTagId());
				userTagDao.save(u);
			}
		}
	}

	@Override
	public UserDetails loadUserByUsername(String logname) throws UsernameNotFoundException {
		if (StringUtils.isBlank(logname)) {
			return null;
		}
		UserDetails user = userDao.findByLogname(logname);
		if (user == null) {
			throw new UsernameNotFoundException("用户的登录名或密码不正确！");
		}
		return user;
	}

}
